Click a button to change the text of text input - javascript

I have this part of code in the Codeigniter controller named 'ajaxcalls' :
public function show_contact_persons($client_id) {
$data['contact_persons'] = $this->common_model->select_records('ci_contact_persons', 'client_id', $client_id);
//dump($data);
function echoArray ($array) {
foreach ($array as $key => $value)
{
if ( true == is_array($value) )
{
echoArray($value);
}
else
{
if ($key == 'contact_person_name') {
echo '<input type="button" value="'.$value.'" onclick="changeContact(987)" /><br />';
}
}
}
}
echoArray($data);
}
and then the JS part at the page which is calling the PHP file :
function changeContact(contact_name) {
document.getElementById('contact_person').value = contact_name;
}
I put the number '987' in this example because the code works only with NUMBERS. When I put text inside the bracket, or what I REALLY want to do :
onclick="changeContact('.$value.')"
then the script doesn't work. ONLY with numbers. What should I change to make it work with strings?

You are very close.
Use this instead :
onclick="changeContact("'.$value.'")"
Whats happening is the JS is rendering it as changeContact(stringValue); so its expecting it to be a defined variable.
Adding the quotations will pass it into the function as a string which will render as : changeContact("stringValue");

Related

Triggering submit event after change when uploading image on Yii2 framework

I am trying to save an image type file by using jquery to trigger the submit. I encountered an issue where it triggers even when the change event is not done.
View create.php:
<?php \yii\bootstrap4\ActiveForm::begin([
'options' => [
'enctype' => 'multipart/form-data',
'id' => 'dynamic-form'
]
]) ?>
<button class="btn btn-primary btn-file">
Select Thumbnail
<input type="file" id="recipeThumbnail" name="recipe">
</button>
<?php \yii\bootstrap4\ActiveForm::end() ?>
In this view, i specify the id to call it in the javascipt file.
Js app.js:
$(function () {
'use strict';
$('#recipeThumbnail').change(ev => {
$(ev.target).closest('form').trigger('submit');
})
});
From my understanding here, the trigger('submit') should only run when there is a change which in this case an image file is selected. However, i suspect the event is triggered and it caused an error of Attempt to read property "name" on null from the model below on the line $this->name = $this->recipe->name;. My other suspicion would be error in the model but i cant wrap my head around where or how it could be.
Model recipe.php:
public function save($runValidaiton = true, $attributeNames = null)
{
$isInsert = $this->isNewRecord;
if ($isInsert) {
$this->recipe_id = Yii::$app->security->generateRandomString(16);
$this->name = $this->recipe->name;
}
$saved = parent::save($runValidaiton, $attributeNames);
if (!$saved) {
return false;
}
if ($isInsert) {
$recipePath = Yii::getAlias('#frontend/web/storage/thumbnail/' . $this->recipe_id . '.jpg');
if (!is_dir(dirname($recipePath))) {
FileHelper::createDirectory(dirname($recipePath));
}
$this->recipe->saveAs($recipePath);
}
return true;
}
Controller RecipeController.php:
public function actionCreate()
{
$model = new Recipe();
$model->recipe = UploadedFile::getInstanceByName('recipe');
if ($this->request->isPost) {
if (Yii::$app->request->isPost && $model->save()) {
return $this->redirect(['view', 'recipe_id' => $model->recipe_id]);
}
} else {
$model->loadDefaultValues();
}
return $this->render('create', [
'model' => $model,
]);
}
I hope i explained this well. Is this error actually caused by the js or something else and any insight on this issue is much appreciated:D
Insights from #ChrisG and #CBroe,
The issue was wrapping the input tag in a button tag which will click both button and input at the same time causing the error. An easy fix would be adding type="button" in the button tag.
But this is actually a broken HTML as an interactive element should not be nested into each other. The fix to this would be using form and labels with the button so that it is a decent html.

Variable returned by Symfony controller always undefined

Ok, so I have a text field in which I type a string and I have a button next to it.
<div class="sidebar-search">
<div class="input-group custom-search-form">
<<label for="riot-summoner-input">Search a Summoner</label><br>
<input type="text" id="riot-summoner-input" class="form-control" placeholder="Type summoner name..." style="margin-bottom: 20px">
<button type="button" id="valid-summoner">Search</button>
</div>
</div>
By Clicking on this button, the following script gets executed
let res = {{ summoner.summonerLevel }}
$(document).ready(function() {
// Get value on button click and pass it back to controller
$("#valid-summoner").click(function () {
const summoner_input = $("#riot-summoner-input").val();
console.log(summoner_input)
let url = `/coach/?summonerName=${summoner_input}`
history.replaceState(summoner_input, 'Coach Index', url);
console.log(url)
function loadXMLDoc()
{
document.getElementById("display-summonerLevel").innerHTML = `Summoner Level: <h2>${res}</h2>`
}
loadXMLDoc();
});
});
Now as far as I can understand this will change my page url to include the value inserted in the text field and will send it back to my controller without refreshing the page, which it does.
Now in my Controller I'm using that value to do some logic with it
/**
* #Route("/", name="app_coach_index", methods={"GET"})
*/
public function index(CoachRepository $coachRepository, riotApi $callRiot, Request $request): ?Response
{
$value = $request->request->get('summoner_input');
if($value != null){
$this->debug_to_console($value . "Hi");
return $this->render('coach/index.html.twig', [
'coaches' => $coachRepository->findAll(), 'summoner'=> $this->showSummoner("$value")
]);}
else{
$this->debug_to_console($value);
return $this->render('coach/index.html.twig', [
'coaches' => $coachRepository->findAll()
]);
}
}
Now it's interesting to note that I'm doing this in the index function.
Here's the function I'm calling within the index function which is actually the one that gets the value from the script
/**
* #Route("/?summonerName={summoner_input}", name="show_summoner", methods={"GET"})
*/
public function showSummoner($summoner_input)
{
$call = new ApiClient(ApiClient::REGION_EUW, 'API-KEY-HERE');
return $call->getSummonerApi()->getSummonerBySummonerName($summoner_input)->getResult();
}
Now that I'm seeing this I can see that the issue is I'm getting the value in the showSummoner() function but trying to use it in the index function. Which is why I'm not getting a value when I print it to console and the variable is undefined.
Honestly I can't think of any logic I can do to overcome this issue.
EDIT!!!!!!!
Okay, so I know where the problem is arising, the issue is when I'm calling showSummoner($value) within index function. I'm using $value = $request->query->get('summoner_input');
I thought I was getting that value in the index function when in fact I'm getting it in the showSummoner() function. You can tell by the annotations
For index I don't have a parameter in its url, whereas in showSummoner() I have a parameter in the annotations as such.
/**
* #Route("/?summonerName={summoner_input}", name="show_summoner", methods={"GET"})
*/
This is indeed the fact because I'm using that url in the script as such
let url = `/coach/?summonerName=${summoner_input}`
The reason for this is I can't use the parameter in the index url because then I would have to provide the parameter in all the other places I'm using index in even when I don't have a parameter meaning I didn't search for anything.
I hope this gives more clarification
You're trying to get a value from $_GET global, not $_POST.
You can replace :
$value = $request->request->get('summoner_input');
by:
$value = $request->query->get('summoner_input');
You are trying to access the GET parameter using the wrong name ('summoner_input').
$value = $request->request->get('summoner_input');
When you are setting it as summonerName here:
let url = `/coach/?summonerName=${summoner_input}`
You will also want to pass a default value to check for, as the second parameter.
Try this:
$value = $request->request->get('summonerName', false);
if(false !== $value){
/* the parameter is in the url */
}

If statement cakephp input value and run a javascript code

I am trying to make an if statement with cakePHP but I'm really an amateur. I checked the cookbook and stackoverflow but couldn't find it. (using 2.x.x version of cake)
So what I'm trying to do is:- if the ticket-1-amount is not zero, remove the invisible class.
Something I tried but didn't work:-
if ( $('#ListTypeTicket-1-amount').val() != '' ) {
$("#invisibleBox").removeClass("invisible");
}
Also tried this:-
if (empty($this->request->data ['ticket-1-amount'] != 0)) {
echo '$("#invisibleBox").removeClass("invisible");</script>';
} ;
My cakePHP form:-
<?=$this->Form->input(
'ticket-1-amount',
array('label' => false,
'class' => 'ticket-1-amount',
'id' => 'ticket-1-amount')
); ?>
This is the actual div
<div id='invisibleBox' class="invisible">
..........
</div>
Keep things simple, Just try:
<div id='invisibleBox' class="<?php if($this->request->data['ticket-1-amount'] == 0) {echo 'invisible'}; ?>">
..........
</div>
Create a JavaScript file and put the code below inside it.
App = {
init: function () {
this.checkTicketAmount();
},
checkTicketAmount: function(){
if ($('#ticket-1-amount').val() != '0') {
$("#invisibleBox").removeClass("invisible");
}
}
};
$(document).ready(function () {
App.init();
});
After the page is loaded, jQuery will check the ticket amount value and remove the invisible class, or not.

Adding JScript to a prestashop CMS page

prestashop v1.5.4.0
I want to add this click to open element made from CSS, HTML and JS located here http://codepen.io/anon/pen/Gqkxv
function openDoor(field) {
var y = $(field).find(".thumb");
var x = y.attr("class");
if (y.hasClass("thumbOpened")) {
y.removeClass("thumbOpened");
}
else {
$(".thumb").removeClass("thumbOpened");
y.addClass("thumbOpened");
}
}
what is the best method to place this in to a CMS page
My guess is since the CMS pages strip out most javascript tags and don't seem to allow you to attach exernal js files you will need to create an override of the cmsController.php.
You would need to create your external js file and css file and save them in the theme's js directory and css directory. The setMedia method is used to attach style/js files when that controller is called. You can override the cmsController.php and add this to the setMedia method
$this->addJS(_THEME_JS_DIR_.'yourjsfile.js');
$this->addCSS(_THEME_CSS_DIR_.'yourcssfile.css');
I believe that should work however, this will add these files to every cms page. The only way I can think to get around that is by getting the ID of the cms page(s) that you want it to appear on and run an if state on your addJS and addCSS functions.
example: You want it to show up on id_cms 4
if ((int)Tools::getValue('id_cms') == 4) {
$this->addJS(_THEME_JS_DIR_.'yourjsfile.js');
$this->addCSS(_THEME_CSS_DIR_.'yourcssfile.css');
}
or you want it to show on id_cms 4 and id_cms 6
if ((int)Tools::getValue('id_cms') == 4 || (int)Tools::getValue('id_cms') == 6) {
$this->addJS(_THEME_JS_DIR_.'yourjsfile.js');
$this->addCSS(_THEME_CSS_DIR_.'yourcssfile.css');
}
no need to add modules,
go to cms.tpl from your theme folder in prestashop,
add this
{if $cms->id==6}
{literal}
<script type="text/javascript" src="js/yourjsfile.js"></script>
{/literal}
{/if}
replace with your cms id and the name of your js file, then upload the file to js folder in prestahop root folder,
then go the prestahop panel, advanced parameters, performance, compile the templates and then launch your site --- the script will run only on the page selected
You can create a module and hook your js to backoffice header like this.
public function install()
{
if ( !$this->installTab()
|| !$this->registerHook('displayBackOfficeHeader'))
return false;
return true;
}
public function hookDisplayBackOfficeHeader()
{
//check if currently updatingcheck if module is currently processing update
if ($this->isUpdating() || !Module::isEnabled($this->name))
return false;
if (method_exists($this->context->controller, 'addJquery'))
{
$this->context->controller->addJquery();
$this->context->controller->addCss($this->_path.'views/css/gamification.css');
if (version_compare(_PS_VERSION_, '1.6.0', '>=') === TRUE)
$this->context->controller->addJs($this->_path.'views/js/gamification_bt.js');
else
$this->context->controller->addJs($this->_path.'views/js/gamification.js');
$this->context->controller->addJqueryPlugin('fancybox');
return $css_str.'<script>
var ids_ps_advice = new Array('.rtrim($js_str, ',').');
var admin_gamification_ajax_url = \''.$this->context->link->getAdminLink('AdminGamification').'\';
var current_id_tab = '.(int)$this->context->controller->id.';
</script>';
}
}
This a example show from prestashop core module gamification. After that you can write your own prestashop js code which you want.
In 2019 regarding PS 1.7 - we solved it here: https://www.prestashop.com/forums/topic/267834-how-to-insert-javascript-code-inside-a-page/
In short - add it directly to CMS content field with slight modifiations:
1) in class/Validation.php add
public static function isCleanHtmlWithScript($html, $allow_iframe = false)
{
$events = 'onmousedown|onmousemove|onmmouseup|onmouseover|onmouseout|onload|onunload|onfocus|onblur|onchange';
$events .= '|onsubmit|ondblclick|onclick|onkeydown|onkeyup|onkeypress|onmouseenter|onmouseleave|onerror|onselect|onreset|onabort|ondragdrop|onresize|onactivate|onafterprint|onmoveend';
$events .= '|onafterupdate|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditfocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onmove';
$events .= '|onbounce|oncellchange|oncontextmenu|oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondeactivate|ondrag|ondragend|ondragenter|onmousewheel';
$events .= '|ondragleave|ondragover|ondragstart|ondrop|onerrorupdate|onfilterchange|onfinish|onfocusin|onfocusout|onhashchange|onhelp|oninput|onlosecapture|onmessage|onmouseup|onmovestart';
$events .= '|onoffline|ononline|onpaste|onpropertychange|onreadystatechange|onresizeend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onsearch|onselectionchange';
$events .= '|onselectstart|onstart|onstop';
if (!$allow_iframe && preg_match('/<[\s]*(i?frame|form|input|embed|object)/ims', $html)) {
return false;
}
return true;
}
2) then in /classes/CMS.php around line #66 change
'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 3999999999999)
to
'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtmlWithScripts', 'size' => 3999999999999)
now you should be good to go

Zend forms working with ajax/javascript onchange event

I am writing a code to use onchange in my application this is my code so far
.Phtml
<script type="text/javascript">
function submit()
{
$id = intval($_GET['id']);
$satellite = intval($_GET['satellite_id']);
if ($id == 0)
{
echo "Please select a Region";
}
else
{
$query = "select * from satellites where region_id = '".$id."'";
$query = mysql_query($query);
echo "<select name='satellite_id'><option value=''>-- select one --</option>";
while ($row = mysql_fetch_assoc($query))
{
echo "<option value='".$row['satellite_id']."'".($row['satellite_id']==$satellite?" selected":"").">".$row['satellite_name']."</option>";
}
echo "</select>";
//DisplayFormRow ("Satellite", FormDropDownBox ("satellite_id", $SatelliteARY, $Result['satellite_id']));
}
}
</script
//zend code Form
$region_name = new Zend_Form_Element_Select('region_name');
$region_name->setAttribs(array('style' => 'width: 150px;'));
$region_name ->setLabel('Region')
->onchange('this.form.submit();') //tried this code ->onchange('javascript:submit();')
->addMultiOption('--Select One--', '--Select One--');
$mdlRegions = new Model_Regions();
$regions = $mdlRegions->getRegions();
foreach ($regions as $region)
{
$region_name->addMultiOption($region->region_id, $region->region_name, $region->region_short_name);
}
//model
<?php
class Model_Regions extends Zend_Db_Table_Abstract
{
protected $_name = 'regions';
//protected $_name = 'smmedetails';
public function getregion($region_id)
{
$region_id = (int)$region_id;
$row = $this->fetchRow('region_id = ' . $region_id);
if (!$row) {
throw new Exception("Could not find row $region_id");
}
return $row->toArray();
}
public function smmedetails2region($region_name)
{
$data = array(
'region_name'=> $region_name
);
return $this->insert($data);
}
public function getRegions()
{
$select = $this->select();
return $this->fetchAll($select);
}
}
//controller
public function registerAction()
{
$this->view->headScript()->appendFile('/js/ui/jquery.ui.autocomplete.js');
$form = new Form_SmmeDetails();
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$companyname = $form->getValue('companyname');
$companytradingname = $form->getValue('companytradingname');
$region_name = $form->getValue('region_name');
$satellite_name = $form->getValue('satellite_name');
$city = $form->getValue('city');
$companyaddress = $form->getValue('companyaddress');
$addresscode = $form->getValue('addresscode');
$companypostaladdress = $form->getValue('companypostaladdress');
$postalcode = $form->getValue('postalcode');
$companyphonenumber = $form->getValue('companyphonenumber');
$companyfaxnumber = $form->getValue('companyfaxnumber');
$companycellnumber = $form->getValue('companycellnumber');
$businessemailaddress = $form->getValue('businessemailaddress');
$businesswebsite = $form->getValue('businesswebsite');
$smmedetails = new Application_Model_DbTable_SmmeDetails();
$smmeid = $smmedetails ->smmedetailsSmmeDetails($companyname, $companytradingname, $region_name, $satellite_name, $city, $companyaddress, $addresscode, $companypostaladdress, $postalcode, $companyphonenumber, $companyfaxnumber,
$companycellnumber, $businessemailaddress, $businesswebsite);
// $region = new Application_Model_DbTable_Region();
//$region ->smmedetails2region($formData, $smmedetails->smmeid);
$this->_redirect('/admin/smme/register2/smmeid/'.$smmeid);
} else {
$form->populate($formData);
}
}
}
The code is suppose to view a hidden input select, called satellite when you select a feild option from regions, the satellite should view certain options based on the region selected. In short the region selected should correspond with what the user selected. eg Province is Gauteng, so cites would be, Johannseburg,Pretoria etc. Take note the region and satellite options are called from the database table according to they names and id. The code above keeps giving me and error Message: Method onchange does not exist. Was told not to use onchange method should I be using ajax and can I use javascript and sqlquery in the view or should I call it as an action? If so how? Here is a slight picture example.
Please be of help
Thanks in advance
I'd make a few suggestions to what you have there.
Firstly, for simplicity, I'd not use the onChange function, because I don't see it in the API, plus JavaScript or jQuery written in that way can become difficult to maintain and write properly. It is a lot simpler to instead include an external JavaScript file. By doing this, you can also test and debug the JavaScript separately, as well as reuse it.
Have a look at the excellent document for onChange, and getJson. I've used these and others and they're quite straight-forward. For testing, I recommend QUnit for starters. It makes testing a breeze.
Secondly, if you're using the Zend libraries for Model_Regions and $region_name, then I'd suggest using them instead of the direct mysql calls as well. This will allow you to build a good library which you can continue to expand as needed, plus it makes composing SQL quicker and safer.
For the controller, I'd suggest a RestController with a Restful Route. Here's an excellent tutorial.
I hope this helps you out with the problem. If you need anything more, let me know.
Thanks for emailing me about this.
The way I go about this is as follows:
Firstly I set up the form, and then an action in a controller.
Lets say getmajorgroupAction()
which in that action I would then disable layout, and just get the relevent results based on the id.
Then in the view file, loop through the
so the output from that call would be
<option value="1">1</option>
<option value="2">2</option>
etc
Personally I use jquery now, whereas the post you referenced when you emailed me, I was using another method.
trying to use something like this
jQuery(document).ready(function() {
jQuery("#division").change(function () {var division = jQuery("#division").val();
jQuery("#major_group").load("/module/getmajorgroup/", {division_id: division} );});
});
Hope that makes sense.
Thanks that was useful but i found a way to do it using this formula below, but everytime I click on the first select the while still in the session the second select appears all the time, eg if a person choose the wrong selection and re tried it brings up another field instead of fixing the field. I think its in a countinous loop . heres my script
<script type="text/javascript">
$(document).ready(function() {
$("#region_name").on('change', function () {
ajaxAddField();
}
);
}
);
// Retrieve new element's html from controller
function ajaxAddField()
{
$.ajax(
{
type: "POST",
url: '<?php echo $this->baseURL()?>/admin/ajax/get-cities/city/' + encodeURIComponent($('#region_name').val()),
success: function(newElement) {
// Insert new element before the Add button
//$(this).prev().remove().end().before('#city-label');
$("#city-label").before(newElement);
}
}
);
}
</script>

Categories